package com.baor.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baor.dao.*;
import com.baor.domain.*;
import com.baor.domain.conf.DistributionConf;
import com.baor.enums.FuncEnum;
import com.baor.service.DistributionGoodsService;
import com.baor.utils.AjaxResult;
import com.baor.utils.RedisUtil;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

import static com.baor.utils.DateUtil.now;

@Service
public class DistributionGoodsServiceImpl implements DistributionGoodsService {

    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private AloneDao aloneDao;

    @Autowired
    private DistributionConfDao confDao;

    @Autowired
    private DistributionLevelDao levelDao;

    @Autowired
    private VipDao userDao;

    @Autowired
    private OrderLogDao logDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private DistributorDao orDao;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private DistributionRecordDao recordDao;

    @Autowired
    private MoneyDao moneyDao;


    private Page<GoodsVo> getPage(Map<String,Object> map){
        if ( map.get("pageIndex") == null || "".equals(map.get("pageIndex")) )
            map.put("pageIndex",1);
        if ( map.get("pageSize") == null || "".equals(map.get("pageSize")) )
            map.put("pageSize",10);
        Long pageIndex = Long.valueOf(map.get("pageIndex").toString());
        Long pageSize = Long.valueOf(map.get("pageSize").toString());
        return new Page<GoodsVo>(pageIndex,pageSize);
    }

    private MPJLambdaWrapper<GoodsVo> getMpj(){
        MPJLambdaWrapper<GoodsVo> mpj = new MPJLambdaWrapper<>();
        mpj
                .selectAll(GoodsVo.class)//不需要第二行的话,第一行一同删除,用这行代替
                .selectFunc(FuncEnum.IF_VIRTUAL,GoodsVo::getGoodsVirtual)//自定义枚举类FuncEnum,(as),主表字段
                .selectFunc(FuncEnum.IF_SELL,GoodsVo::getGoodsSell)
                .selectFunc(FuncEnum.IF_TRUE,GoodsVo::getGoodsDistribution)
                .selectFunc(FuncEnum.IF_DEFAULT,GoodsVo::getDefaultDistribution);
        return mpj;
    }

    @Override
    public AjaxResult<?> list(Map<String, Object> map) {
        Page<GoodsVo> page = goodsDao.selectPage(getPage(map), getMpj());
        List<GoodsVo> records = page.getRecords();
        long pages = page.getPages();
        Map<String,Object> res = new HashMap<>();
        res.put("pageCount",pages);
        res.put("list",records);
        return AjaxResult.success(res);
    }

    @Override
    public AjaxResult<?> insert(List<Integer> its) {
        goodsDao.updateGoodsDistribution(its);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult<?> delete(List<Integer> its) {
        goodsDao.deleteGoodsDistribution(its);
        goodsDao.deleteDefault(its);
        aloneDao.deleteAlone(its);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult<?> search(Map<String, Object> map) {
        MPJLambdaWrapper<GoodsVo> mpj = getMpj();
        if ( map.get("goodsName") != null && ! "".equals(map.get("goodsName")) )//=
            mpj.like(GoodsVo::getGoodsName,map.get("goodsName"));
        if ( map.get("separateId") != null && ! "".equals(map.get("separateId")) )//!=
            mpj.eq(GoodsVo::getSeparateId,map.get("separateId"));
        if ( map.get("goodsVirtual") != null && ! "".equals(map.get("goodsVirtual")) )//like
            mpj.eq(GoodsVo::getGoodsVirtual,map.get("goodsVirtual"));
        Page<GoodsVo> page = goodsDao.selectPage(getPage(map),mpj);
        List<GoodsVo> records = page.getRecords();
        long pages = page.getPages();
        Map<String,Object> res = new HashMap<>();
        res.put("pageCount",pages);
        res.put("list",records);
        return AjaxResult.success(res);
    }

    /**
     * 通过订单获取信息实现分销返现
     * @param
     * @return
     */
    @Override
    public AjaxResult<?> disMoney(Integer logId) {
        OrderLogVo logVo = logDao.selectById(logId);
        //订单
        String orderId = logVo.getOrderId();
        OrderVo orderVo = orderDao.selectById(orderId);
        //买家
        String userId = orderVo.getUserId();
        UserVo userVo = userDao.selectById(userId);
        //订单所购买商品
        String goodsId = orderVo.getGoodsId();
        GoodsVo goodsVo = goodsDao.selectById(goodsId);
        String siteId = goodsVo.getSiteId();
        //站点配置
        DistributionConf conf = confDao.selectOne(new LambdaQueryWrapper<DistributionConf>()
                .eq(DistributionConf::getSiteId,siteId));
        System.out.println(logVo);
        if ( conf.getConfOpen().equals(0) )
            return AjaxResult.error("当前商品所在站点未开启分销返现",null);
        if ( goodsVo.getGoodsDistribution().equals(0) )
            return AjaxResult.error("当前商品未开启分销返现",null);
//        if( conf.getConfConsumeCondition().equals(0) && !logVo.getOrderStatusId().equals("3") )//消费条件 3->付款,12->订单完成
//            return AjaxResult.error("orderLog的状态不是3,没有分销返现",null);
//        else if ( conf.getConfConsumeCondition().equals(1) && !logVo.getOrderStatusId().equals("12") )
//            return AjaxResult.error("orderLog的状态不是12,没有分销返现",null);
        if ( !logVo.getOrderStatusId().equals("12") )
            return AjaxResult.error("orderLog的状态不是12,没有分销返现",null);
//        System.out.println("分销返现^_^");
        Integer buyer = Integer.valueOf(userId);
        Integer superior = Integer.valueOf(userVo.getUserSuperior());
        Integer superParent = 0;
        if ( superior != null && superior.compareTo(0) != 0 )//有上级分销商
            superParent = Integer.valueOf(userDao.selectOne(new LambdaQueryWrapper<UserVo>()
                    .eq(UserVo::getUserId, superior))
                    .getUserSuperior());
        DistributorVo distributorVo = orDao.selectOne(new LambdaQueryWrapper<DistributorVo>()
                .eq(DistributorVo::getUserId, buyer));
//        Integer confSelf = conf.getConfSelf();// 0 -> 未开始自购分佣
//        if ( conf.getConfSelf().compareTo(1) == 0 ){//开启自购分佣
//            superParent = superior;
//            superior = buyer;
//        }// superior + superParent
        if ( conf.getConfSelf().compareTo(1) == 0 && distributorVo != null ){//开启
            superParent = superior;
            superior = buyer;
        }
//        orDao.selectOne(new LambdaQueryWrapper<DistributorVo>().in(DistributorVo::getUserId,buyer));
//        Integer confLevel = conf.getConfLevel();//0 -> 一级
        DistributorVo or1 = orDao.selectOne(new LambdaQueryWrapper<DistributorVo>().eq(DistributorVo::getUserId, superior));
        DistributorVo or2 = orDao.selectOne(new LambdaQueryWrapper<DistributorVo>().eq(DistributorVo::getUserId, superParent));
        //获取商品奋勇设置
        String defaultion = goodsVo.getDefaultDistribution();
        BigDecimal firstLevel1 = null;
        BigDecimal secondLevel2 = BigDecimal.ZERO;
        //默认分佣规则
        BigDecimal num = new BigDecimal(orderVo.getOrderGoodsNum());//购买数量
        BigDecimal priceValue = orderVo.getPriceValue();//商品价格
        BigDecimal orderSubtract = orderVo.getOrderSubtract();//优惠劵金额
        BigDecimal multiply = num.multiply(priceValue);//数量 x 价格
        BigDecimal total = multiply.subtract(orderSubtract);//总价 - 优惠劵
        total = total.divide(new BigDecimal(100));//百分比
        //商品若存在单独规则
        if ( goodsVo.getDefaultDistribution().equals(0) ){//默认分销规则
            List<DistributionLevelVo> distributionLevelVos = levelDao.selectList(null);
            for ( DistributionLevelVo x : distributionLevelVos ){
                if ( or1 != null && x.getDistributionLevelId().equals(or1.getDistributionLevelId()) )
                    firstLevel1 = x.getFirstLevel();
                if ( or2 != null && x.getDistributionLevelId().equals(or2.getDistributionLevelId()) )
                    secondLevel2 = x.getSecondLevel();
            }
        } else {
            List<AloneVo> aloneVos = aloneDao.selectList(new LambdaQueryWrapper<AloneVo>()
                    .eq(AloneVo::getGoodsId, goodsId));
            if ( aloneVos.size() == 1 && aloneVos.get(0).getAloneMoney().compareTo(BigDecimal.ZERO) > 0 ){
                /**
                * 固定金额
                */
                BigDecimal aloneMoney = aloneVos.get(0).getAloneMoney();
                if ( or1 != null )
                    distribution(or1,aloneMoney,total,BigDecimal.ZERO,priceValue,orderVo,0,true);
                return AjaxResult.success("(o^^o)");
            }
            for ( AloneVo x : aloneVos ){
                if ( or1 != null && x.getDistributionLevelId().equals(or1.getDistributionLevelId()) )
                    firstLevel1 = x.getFirstLevel();
                if ( or2 != null && x.getDistributionLevelId().equals(or2.getDistributionLevelId()) )
                    secondLevel2 = x.getSecondLevel();
            }
        }
        //默认一级分佣的计算
        if ( or1 != null ){
            BigDecimal disMoney = total.multiply(firstLevel1);//成交价 x 比例
            distribution(or1,disMoney,total,firstLevel1,priceValue,orderVo,0,false);
        }
        if ( or2 != null ){
            BigDecimal disMoney = total.multiply(secondLevel2);//成交价 x 比例
            distribution(or2,disMoney,total,secondLevel2,priceValue,orderVo,1,false);
        }
        return AjaxResult.success("^o^");
    }

    /**
     *
     * @param or1   分销商
     * @param disMoney  分销金额
     * @param total 订单成交价
     * @param firstLevel1   改分销商或佣金比例
     * @param priceValue    商品单价
     * @param orderVo   订单
     * @param number   受益等级
     * @param flag  false -> 比例 true -> 固定
     */
    private void distribution(DistributorVo or1,BigDecimal disMoney,BigDecimal total,BigDecimal firstLevel1,BigDecimal priceValue,OrderVo orderVo,Integer number,boolean flag){
        /**
         *  distributor
         */
//        Map<String,Object> map = new HashMap<>();
//        map.put("distributorId",or1.getDistributorId());
//        map.put("changeMoney",disMoney);
//        orDao.updateDisMoney(map);//一级分佣持久化 - distributor
        /**
         *  record
         */
        DistributionRecordVo record = new DistributionRecordVo();
        record.setFinalMoney(disMoney);
        record.setGoodsValue(priceValue);
        record.setPriceCost(total.multiply(new BigDecimal(100)));
        if ( flag ){
            record.setDefaultDistribution(1);
            record.setAloneMoney(disMoney);
        }
        else{
            record.setDefaultDistribution(0);
            record.setAloneMoney(BigDecimal.ZERO);
        }
        record.setMoneyLevel(firstLevel1.toString());
        record.setDistributionLevel(number.toString());//身为几级分销人获益
        record.setGoodsNum(orderVo.getOrderGoodsNum());
        record.setCreateTime(now());
        record.setUserId(or1.getUserId());
        record.setOrderId(orderVo.getOrderId().toString());
        record.setDistributionStatus("0");
        record.setRecordsCode(random());
        record.setGoodsId(orderVo.getGoodsId());
        record.setSiteId(or1.getSiteId());
        recordDao.insert(record);//分佣记录持久化
        /**
         *  money
         */
        UserVo userVo1 = userDao.selectOne(new LambdaQueryWrapper<UserVo>().eq(UserVo::getUserId, or1.getUserId()));
        MoneyVo money = new MoneyVo();
        money.setUserName(userVo1.getUserName());
        money.setUserTel(userVo1.getUserTel());
        money.setCreateTime(now());
        money.setMoneyChange(disMoney);
        money.setMoneyFinal(userVo1.getUserCanuseMoney().add(disMoney));
        money.setUserId(or1.getUserId());
        money.setAccountType("余额");
        money.setCreateTime(now());
        money.setSiteId(orderVo.getSiteId());
        money.setMoneySourceId("佣金返现");
        money.setMoneyStatus("0");
//        money.setPriceCost(total.multiply(new BigDecimal(100)));
        moneyDao.insert(money);
        /**
         *  user
         */
        userVo1.setUserCantBe(userVo1.getUserCantBe().add(disMoney));
        userVo1.setUserDistributionMoney(userVo1.getUserDistributionMoney().add(disMoney));
        userVo1.setUserTotalDistribution(userVo1.getUserTotalDistribution().add(disMoney));
        userVo1.setUserCanuseMoney(userVo1.getUserCanuseMoney().add(disMoney));
        userVo1.setUserTotalMoney(userVo1.getUserTotalMoney().add(disMoney));
        userDao.updateById(userVo1);
    }

    private String random(){
        StringBuilder builder = new StringBuilder();
        return builder
                .append("DGSI")
                .append(System.currentTimeMillis())
                .append(Math.random() * 543612 + 123456)
                .toString();
    }
}
